import os
import cv2
import numpy as np
import pyvirtualcam
from pyvirtualcam import PixelFormat
import threading
import queue
import time
from pydub import AudioSegment
from pydub.playback import play

# 视频源，可以是本地文件路径或流媒体地址
video_source = r"C:\Users\happy\Downloads\videoplayback.mp4"

# 初始化视频捕获
cap = cv2.VideoCapture(video_source)

if not cap.isOpened():
    print("无法打开视频源！")
    exit()

# 获取视频帧率
fps = cap.get(cv2.CAP_PROP_FPS)
if fps <= 0:  # 如果视频文件没有正确的帧率信息
    fps = 30  # 手动设置帧率

# 设置目标分辨率（适合快手直播）
target_width = 1280  # 720p
target_height = 720

print(f"目标分辨率：{target_width}x{target_height}, 帧率：{fps}")

# 定义帧队列以缓冲帧数据
frame_queue = queue.Queue(maxsize=10)

# 读取视频帧的线程
def read_frames():
    while True:
        start_time = time.perf_counter()  # 更高精度的计时

        ret, frame = cap.read()
        if not ret:
            print("视频播放结束，重新开始...")
            cap.set(cv2.CAP_PROP_POS_FRAMES, 0)  # 重新播放
            continue

        # 将帧放入队列中
        if not frame_queue.full():
            frame_queue.put(frame)

        # 控制帧读取速度，匹配视频的实际帧率
        elapsed_time = time.perf_counter() - start_time
        time_to_wait = max(1.0 / fps - elapsed_time, 0)
        time.sleep(time_to_wait)

# 提取音频并播放
def play_audio():
    try:
        audio = AudioSegment.from_file(video_source)
        play(audio)
    except IndexError:
        print("视频文件中没有音频流，跳过音频播放...")
    except Exception as e:
        print(f"提取音频时发生错误: {e}")

# 启动读取线程
read_thread = threading.Thread(target=read_frames, daemon=True)
read_thread.start()

# 启动音频播放线程
audio_thread = threading.Thread(target=play_audio, daemon=True)
audio_thread.start()

# 使用 pyvirtualcam 发送帧到虚拟摄像头
try:
    with pyvirtualcam.Camera(width=target_width, height=target_height, fps=int(fps), fmt=PixelFormat.BGR) as cam:
        print(f"虚拟摄像头已启动：{cam.device}")

        while True:
            if not frame_queue.empty():
                # 丢弃旧帧，只获取最新帧
                while not frame_queue.empty():
                    frame = frame_queue.get()

                # 调整帧分辨率为目标分辨率
                frame = cv2.resize(frame, (target_width, target_height), interpolation=cv2.INTER_LINEAR)

                # 显示视频帧（可选）
                cv2.imshow("Video Stream", frame)

                # 将帧发送到虚拟摄像头
                cam.send(frame)
                cam.sleep_until_next_frame()

            # 按下 'q' 键退出
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
except KeyboardInterrupt:
    print("程序被中断，正在清理资源...")
finally:
    cap.release()
    cv2.destroyAllWindows()
